<?php
require_once 'vendor/autoload.php';

/**
 * 消息推送驱动器组件：SMS.ChinaSMS[消息子模型-SMS.中国短信网]
 * 
 * @date	2017年7月19日 下午7:30:22
 * 
 */
class MessagePusherSms_ChinaSMS extends CI_Driver implements libraries\common\MessagePusherInterface
{
	const DEBUG_MODE = false;
// 	private static $userId   = '';
// 	private static $userPass = '';
	private $userName    = '';
	private $userPass    = '';
	private $cGroupId    = '';
	private $signature   = '';
	private $url         = 'http://smsapi.c123.cn/OpenPlatform/OpenApi';
	private $lastResponse       = null;
	
	public function __set($var, $val)
	{
		$this->$var = $val;
	}
	
	public function __construct($config = array())
	{
		
	}
	
	/**
	 * 给定数据执行推送
	 *
	 * @param array $data
	 *
	 * @return void
	 */
	public function pushPerform($data)
	{
		if(self::DEBUG_MODE) {
			return ;
		}
		$mobile  = $data['mobile'];
		$message = $data['msg'];
		$this->lastResponse = $this->send($mobile, $message);
	}
	
	/**
	 * 获取上一次推送的状态
	 *
	 * @return boolean
	 */
	public function getStatus()
	{
		if(self::DEBUG_MODE) {
			return true;
		}
		$myParsedResponse = $this->getParsedResponse();
		if($myParsedResponse && $myParsedResponse['status'] == 'success') {
			return true;
		}
		
		return false;
	}
	
	public function getMessage()
	{
		$myParsedResponse = $this->getParsedResponse();
		if($myParsedResponse) {
			return $myParsedResponse['message'];
		}
		
		return false;
	}
	
	private function getParsedResponse()
	{
		if(!isset($this->lastResponse)) {
			//FIXME trigger_error???
// 			<h4>A PHP Error was encountered</h4>
// 			<p>Severity: User Error</p>
// 			<p>Message:  MessagePusherSms_XFunionSMS::MessagePusherSms_XFunionSMS::getParsedResponse: You Shouldn't call me here, because no response now!</p>
// 			<p>Filename: drivers/MessagePusherSms_XFunionSMS.php</p>
// 			<p>Line Number: 79</p>
			//trigger_error(sprintf("%s::%s: You Shouldn't call me here, because no response now!", __CLASS__, __METHOD__), E_USER_ERROR);
			return false;
		}
		
		$response = $this->lastResponse;
		
		$myParsedResponse = array();
		preg_match_all('/result="(.*?)"/', $response, $res);
		if(trim($res[1][0]) == '1' )  //发送成功 ，返回企业编号，员工编号，发送编号，短信条数，单价，余额
		{
			preg_match_all('/\<Item\s+(.*?)\s+\/\>/',$response,$item);
			for($i=0;$i<count($item[1]);$i++){
				preg_match_all('/cid="(.*?)"/',$item[1][$i],$cid);
				preg_match_all('/sid="(.*?)"/',$item[1][$i],$sid);
				preg_match_all('/msgid="(.*?)"/',$item[1][$i],$msgid);
				preg_match_all('/total="(.*?)"/',$item[1][$i],$total);
				preg_match_all('/price="(.*?)"/',$item[1][$i],$price);
				preg_match_all('/remain="(.*?)"/',$item[1][$i],$remain);
				
				$send['cid']=$cid[1][0];        //企业编号
				$send['sid']=$sid[1][0];        //员工编号
				$send['msgid']=$msgid[1][0];    //发送编号
				$send['total']=$total[1][0];    //计费条数
				$send['price']=$price[1][0];    //短信单价
				$send['remain']=$remain[1][0];  //余额
				$send_arr[]=$send;         //数组send_arr 存储了发送返回后的相关信息
			}
			$myParsedResponse['status'] = 'success';
			$myParsedResponse['message'] = $res[1][0];//发送成功返回的值
			$myParsedResponse['send'] = $send_arr;
		}
		else  //发送失败的返回值
		{
			$errorMsg = array(
					'0' => '帐户格式不正确(正确的格式为:员工编号@企业编号)',
					'-1' => '服务器拒绝(速度过快、限时或绑定IP不对等)如遇速度过快可延时再发',
					'-2' => ' 密钥不正确',
					'-3' => '密钥已锁定',
					'-4' => '参数不正确(内容和号码不能为空，手机号码数过多，发送时间错误等)',
					'-5' => '无此帐户',
					'-6' => '帐户已锁定或已过期',
					'-7' => '帐户未开启接口发送',
					'-8' => '不可使用该通道组',
					'-9' => '帐户余额不足',
					'-10' => '内部错误',
					'-11' => '扣费失败',
			);
			
			$myParsedResponse['status'] = 'error';
			$myParsedResponse['message'] = @$errorMsg[$res[1][0]];
			$myParsedResponse['send'] = array();
		}
		
		//print_r($myParsedResponse);
		return $myParsedResponse;
	}
	
	private function send($mobile, $message)
	{
		$count = count(explode(",", $mobile));
		$message = array_fill(0, $count, $message);
		$message = implode("{|}", $message);
		$action = $count > 1 ? 'sendBatch' : 'sendOnce';
		$params = array(
				'action'    => $action,  //发送类型 ，可以有sendOnce短信发送，sendBatch一对一发送，sendParam	动态参数短信接口
				'ac'        => $this->userName, //用户账号
				'authkey'   => $this->userPass, //认证密钥
				'cgid'      => $this->cGroupId, //通道组编号
				'm'         => $mobile,         //号码,多个号码用逗号隔开
				'c'         => $message,        //如果页面是gbk编码，则转成utf-8编码，如果是页面是utf-8编码，则不需要转码,内容用{|}，如测试一{|}测试二
				'csid'      => $this->signature,//签名编号 ，可以为空，为空时使用系统默认的签名编号
				't'         => '',              //发送时间,可以为空表示立即发送,yyyyMMddHHmmss 如:20130721182038
		);
		//$params = http_build_query($params);
		//print_r($params);
		
		return self::postSMS($this->url, $params);
	}
	
	private static function postSMS($url, $data='')
	{
		$row = parse_url($url);
		$host = $row['host'];
		$port = @$row['port'] ? $row['port']:80;
		$file = $row['path'];
		while (list($k,$v) = each($data))
		{
			@$post .= rawurlencode($k)."=".rawurlencode($v)."&";	//转URL标准码
		}
		$post = substr( $post , 0 , -1 );
		$len = strlen($post);
		$fp = @fsockopen( $host ,$port, $errno, $errstr, 10);
		if (!$fp) {
			return "$errstr ($errno)\n";
		} else {
			$receive = '';
			$out = "POST $file HTTP/1.0\r\n";
			$out .= "Host: $host\r\n";
			$out .= "Content-type: application/x-www-form-urlencoded\r\n";
			$out .= "Connection: Close\r\n";
			$out .= "Content-Length: $len\r\n\r\n";
			$out .= $post;
			fwrite($fp, $out);
			while (!feof($fp)) {
				$receive .= fgets($fp, 128);
			}
			fclose($fp);
			$receive = explode("\r\n\r\n",$receive);
			unset($receive[0]);
			//print_r($receive);
			return implode("",$receive);
		}
	}
	
}